/**
 * @author lwlianghehe@gmail.com
 * @date 2024/11/22
 */

import {postErpHttp, postErpHttpWithConfig} from "./http.ts";
import PageParam from "../model/PageParam.ts";
import {getPageSize} from "./env.ts";
import ServiceConditionPage from "../model/ServiceConditionPage.ts";
import ServiceInvokeParam from "../model/ServiceInvokeParam.ts";
import {useServiceStore} from "../global/store/serviceStore.ts";

export function getModelSelectionApi(serviceName: string, fields: string): Promise<any> {
    return postErpHttp(`/service/get/${serviceName}/selection/map`, {serviceName, fields})
}


export function getServiceFieldApi(serviceName: string, field?: string): Promise<any> {
    const param: any = {serviceName}
    if (field) {
        param['field'] = field
    }
    return postErpHttp(`/service/get/${serviceName}/fields`, param)
}

export function saveMultiModelApi(value: Object[], serviceName: string): Promise<any> {
    return postErpHttp(`/service/${serviceName}/save`, value)
}


export function addModelApi(value: Object, serviceName: string): Promise<any> {
    return postErpHttp(`/service/${serviceName}/add`, {serviceName, value})
}

export function createModelApi(value: Object, serviceName: string) {
    return postErpHttp(`/service/${serviceName}/create`, {serviceName, value})
}

export function getModelDetailApi(id: number, fields: string, serviceName: string): Promise<any> {
    return postErpHttp(`/service/get/${serviceName}/detail`, {
        serviceName,
        fields,
        condition: `('id',=,${id})`
    })
}

export function editModelApi(value: Object, serviceName: string): Promise<any> {
    return postErpHttp(`/service/${serviceName}/update`, {serviceName, value})
}

export function getModelPageApi(fields: string,
                                condition: string,
                                serviceName: string,
                                pageNum: number,
                                pageSize?: number): Promise<any> {
    const af = async () => {
        const serviceStore = useServiceStore();
        const service = await serviceStore.getServiceByNameAsync(serviceName)
        const pageParam: PageParam = {pageNum, pageSize: pageSize ? pageSize : getPageSize()}
        const param: ServiceConditionPage = {
            serviceName,
            page: pageParam,
            fields,
            order: `${service.keyField} desc`,
            isDistinct: true,
            condition
        }

        return postErpHttp(`/service/get/${serviceName}/page`, param)
    }
    return af()
}

export function deleteModelApi(id: number, serviceName: string) {
    return postErpHttp(`/service/${serviceName}/delete`, {serviceName, id})
}

export function deleteMultiModelApi(ids: any[], serviceName: string) {
    return postErpHttp(`/service/${serviceName}/delete`, {serviceName, ids})
}

export function getModelAllApi(fields: string,
                               condition: string,
                               serviceName: string) {
    const af = async () => {
        const param: any = {fields, condition, serviceName};
        const serviceStore = useServiceStore();
        const service = await serviceStore.getServiceByNameAsync(serviceName)
        param.order = `${service.keyField} desc`;
        return postErpHttp(`/service/get/${serviceName}/all`, param);
    }
    return af()
}


export async function invokeMethod(serviceName: string, param: ServiceInvokeParam) {
    try {
        // 首先尝试以JSON格式请求，检查是否为文件下载
        const response = await postErpHttpWithConfig(`/service/invoke/${serviceName}/method`, param,
             {returnFullResponse: true});
        
        // 检查响应头，判断是否为文件下载
        if (response.headers && response.headers['content-type']) {
            const contentType = response.headers['content-type'];
            
            // 如果是文件类型，重新以blob格式请求
            if (contentType.includes('application/octet-stream') || 
                contentType.includes('application/pdf') ||
                contentType.includes('application/vnd.openxmlformats-officedocument') ||
                contentType.includes('application/vnd.ms-excel') ||
                contentType.includes('text/csv') ||
                contentType.includes('image/') ||
                contentType.includes('audio/') ||
                contentType.includes('video/') ||
                contentType.includes('application/zip') ||
                contentType.includes('application/x-zip-compressed')) {
                
                // 重新以blob格式请求文件
                const fileResponse = await postErpHttpWithConfig(`/service/invoke/${serviceName}/method`, param,
                     {returnFullResponse: true, responseType: 'blob'});
                
                // 创建下载链接
                const blob = new Blob([fileResponse.data], { type: contentType });
                const url = window.URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                
                // 从响应头获取文件名，如果没有则使用默认名称
                const contentDisposition = fileResponse.headers['content-disposition'];
                let filename = `${serviceName}_${new Date().getTime()}`;
                
                if (contentDisposition) {
                    const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
                    if (filenameMatch && filenameMatch[1]) {
                        filename = filenameMatch[1].replace(/['"]/g, '');
                    }
                }
                
                link.download = filename;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                window.URL.revokeObjectURL(url);
                
                return { success: true, message: '文件下载成功' };
            }
        }
        
        // 如果不是文件，返回 JSON 数据
        return response.data || response;
        
    } catch (error) {
        console.error('方法调用失败:', error);
        throw error;
    }
}